WebCodecs ImageDecoder API์ ๊ธฐ๋ฅ, ์ง์ ํฌ๋งท, ์ฑ๋ฅ ๊ณ ๋ ค์ฌํญ ๋ฐ ์น ์ ํ๋ฆฌ์ผ์ด์ ์์์ ๊ณ ๊ธ ์ด๋ฏธ์ง ์ฒ๋ฆฌ๋ฅผ ์ํ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์์๋ณด์ธ์.
WebCodecs ImageDecoder: ์ต์ ์ด๋ฏธ์ง ํฌ๋งท ์ฒ๋ฆฌ์ ๋ํ ์ฌ์ธต ํ๊ตฌ
WebCodecs API๋ ์น ๋ฉํฐ๋ฏธ๋์ด ๊ธฐ๋ฅ์ ์ค์ํ ๋ฐ์ ์ ์๋ฏธํฉ๋๋ค. ์ด API๋ ์น ๊ฐ๋ฐ์์๊ฒ ๋ธ๋ผ์ฐ์ ์ ๋ด์ฅ๋ ๋ฏธ๋์ด ์ฝ๋ฑ์ ๋ํ ๋ก์ฐ๋ ๋ฒจ ์ก์ธ์ค๋ฅผ ์ ๊ณตํ์ฌ, ์๋ฐ์คํฌ๋ฆฝํธ์์ ์ง์ ๋ณต์กํ ์ค๋์ค ๋ฐ ๋น๋์ค ์ฒ๋ฆฌ ์์
์ ์ํํ ์ ์๊ฒ ํด์ค๋๋ค. WebCodecs์ ํต์ฌ ๊ตฌ์ฑ ์์ ์ค ImageDecoder API๋ ๋ค์ํ ์ด๋ฏธ์ง ํฌ๋งท์ ์กฐ์ํ๊ณ ์์
ํ๊ธฐ ์ํ ๊ฐ๋ ฅํ ๋๊ตฌ๋ก ๋๋ณด์
๋๋ค. ์ด ์ข
ํฉ ๊ฐ์ด๋์์๋ ImageDecoder์ ๊ธฐ๋ฅ, ์ง์ ํฌ๋งท, ์ฌ์ฉ ์ฌ๋ก ๋ฐ ์ฑ๋ฅ ๊ณ ๋ ค์ฌํญ์ ํ๊ตฌํ๋ฉฐ ๊ทธ ๋ณต์ก์ฑ์ ๊น์ด ํํค์ณ ๋ณด๊ฒ ์ต๋๋ค.
WebCodecs ImageDecoder๋ ๋ฌด์์ธ๊ฐ?
ImageDecoder๋ ์น ์ ํ๋ฆฌ์ผ์ด์
์ด ๋ธ๋ผ์ฐ์ ๋ด์์ ์ง์ ์ด๋ฏธ์ง ๋ฐ์ดํฐ๋ฅผ ๋์ฝ๋ฉํ ์ ์๊ฒ ํด์ฃผ๋ ์๋ฐ์คํฌ๋ฆฝํธ API์
๋๋ค. ๋ธ๋ผ์ฐ์ ์ ๋ด์ฅ ์ด๋ฏธ์ง ์ฒ๋ฆฌ์ ์์กดํ๋ ๊ธฐ์กด ๋ฐฉ๋ฒ๊ณผ ๋ฌ๋ฆฌ, ImageDecoder๋ ๋์ฝ๋ฉ ํ๋ก์ธ์ค์ ๋ํ ์ธ๋ฐํ ์ ์ด๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด๋ฌํ ์ ์ด๋ ๊ณ ๊ธ ์ด๋ฏธ์ง ์กฐ์, ์ค์๊ฐ ์ฒ๋ฆฌ, ๊ทธ๋ฆฌ๊ณ ํฌ๊ฑฐ๋ ๋ณต์กํ ์ด๋ฏธ์ง๋ฅผ ํจ์จ์ ์ผ๋ก ๋ค๋ฃจ๋ ๋ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค.
ImageDecoder์ ์ฃผ์ ๋ชฉ์ ์ ์ธ์ฝ๋ฉ๋ ์ด๋ฏธ์ง ๋ฐ์ดํฐ(์: JPEG, PNG, WebP)๋ฅผ ๊ฐ์ ธ์ ๋ ๋๋ง, ๋ถ์ ๋๋ ์ถ๊ฐ ์ฒ๋ฆฌ์ ์ฆ์ ์ฌ์ฉํ ์ ์๋ ์์ ํฝ์
๋ฐ์ดํฐ๋ก ๋ณํํ๋ ๊ฒ์
๋๋ค. ์ด๋ ๋ธ๋ผ์ฐ์ ์ ๊ธฐ๋ณธ ์ด๋ฏธ์ง ์ฝ๋ฑ๊ณผ ์ํธ ์์ฉํ๊ธฐ ์ํ ํ์คํ๋ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ์ฌ, ๋ค์ํ ์ด๋ฏธ์ง ํฌ๋งท์ ๋ณต์ก์ฑ์ ์ถ์ํํฉ๋๋ค.
์ฃผ์ ๊ธฐ๋ฅ ๋ฐ ์ด์
- ๋ก์ฐ๋ ๋ฒจ ์ก์ธ์ค: ์ด๋ฏธ์ง ์ฝ๋ฑ์ ์ง์ ์ก์ธ์คํ์ฌ ๋์ฝ๋ฉ ๋งค๊ฐ๋ณ์์ ๋ํ ๊ณ ๊ธ ์ ์ด๋ฅผ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
- ํฌ๋งท ์ง์: AVIF ๋ฐ WebP์ ๊ฐ์ ์ต์ ์ฝ๋ฑ์ ํฌํจํ ๊ด๋ฒ์ํ ์ด๋ฏธ์ง ํฌ๋งท์ ์ง์ํฉ๋๋ค.
- ์ฑ๋ฅ: ๋์ฝ๋ฉ ์์ ์ ๋ธ๋ผ์ฐ์ ์ ์ต์ ํ๋ ์ฝ๋ฑ์ ์คํ๋ก๋ํ์ฌ ์๋ฐ์คํฌ๋ฆฝํธ ๊ธฐ๋ฐ ๋์์ ๋นํด ์ฑ๋ฅ์ ํฅ์์ํต๋๋ค.
- ๋น๋๊ธฐ ์์ : ๋น๋๊ธฐ API๋ฅผ ํ์ฉํ์ฌ ๋ฉ์ธ ์ค๋ ๋ ์ฐจ๋จ์ ๋ฐฉ์งํ๊ณ ๋ถ๋๋ฌ์ด ์ฌ์ฉ์ ๊ฒฝํ์ ๋ณด์ฅํฉ๋๋ค.
- ์ฌ์ฉ์ ์ ์: ๊ฐ๋ฐ์๊ฐ ์ค์ผ์ผ๋ง ๋ฐ ์ ๊ณต๊ฐ ๋ณํ๊ณผ ๊ฐ์ ๋์ฝ๋ฉ ์ต์ ์ ์ฌ์ฉ์ ์ ์ํ ์ ์์ต๋๋ค.
- ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ: ๋์ฝ๋ฉ๋ ์ด๋ฏธ์ง ๋ฒํผ์ ๋ํ ์ ์ด๋ฅผ ์ ๊ณตํ์ฌ ํจ์จ์ ์ธ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
์ง์๋๋ ์ด๋ฏธ์ง ํฌ๋งท
ImageDecoder๋ ๋ค์ํ๊ณ ์ธ๊ธฐ ์๋ ์ต์ ์ด๋ฏธ์ง ํฌ๋งท์ ์ง์ํฉ๋๋ค. ์ง์๋๋ ํน์ ํฌ๋งท์ ๋ธ๋ผ์ฐ์ ์ ํ๋ซํผ์ ๋ฐ๋ผ ์ฝ๊ฐ ๋ค๋ฅผ ์ ์์ง๋ง, ๋ค์์ ์ผ๋ฐ์ ์ผ๋ก ์ง์๋๋ ํฌ๋งท์
๋๋ค:
- JPEG: ์ฌ์ง ๋ฐ ๋ณต์กํ ์ด๋ฏธ์ง์ ์ ํฉํ ๋๋ฆฌ ์ฌ์ฉ๋๋ ์์ค ์์ถ ํฌ๋งท์ ๋๋ค.
- PNG: ์ ๋ช ํ ์ , ํ ์คํธ, ๊ทธ๋ํฝ์ด ์๋ ์ด๋ฏธ์ง์ ์ด์์ ์ธ ๋ฌด์์ค ์์ถ ํฌ๋งท์ ๋๋ค.
- WebP: ๊ตฌ๊ธ์ด ๊ฐ๋ฐํ ์ต์ ์ด๋ฏธ์ง ํฌ๋งท์ผ๋ก, JPEG ๋ฐ PNG์ ๋นํด ์ฐ์ํ ์์ถ๋ฅ ๊ณผ ํ์ง์ ์ ๊ณตํฉ๋๋ค. ์์ค ๋ฐ ๋ฌด์์ค ์์ถ์ ๋ชจ๋ ์ง์ํฉ๋๋ค.
- AVIF: AV1 ๋น๋์ค ์ฝ๋ฑ์ ๊ธฐ๋ฐ์ผ๋ก ํ ๊ณ ์ฑ๋ฅ ์ด๋ฏธ์ง ํฌ๋งท์ ๋๋ค. ํนํ ๋ณต์กํ ์ด๋ฏธ์ง์ ๋ํด ๋ฐ์ด๋ ์์ถ๋ฅ ๊ณผ ์ด๋ฏธ์ง ํ์ง์ ์ ๊ณตํฉ๋๋ค.
- BMP: ๊ฐ๋จํ ๋น์์ถ ์ด๋ฏธ์ง ํฌ๋งท์ ๋๋ค.
- GIF: ์ ๋๋ฉ์ด์ ์ด๋ฏธ์ง์ ๊ฐ๋จํ ๊ทธ๋ํฝ์ ํํ ์ฌ์ฉ๋๋ ๋ฌด์์ค ์์ถ ํฌ๋งท์ ๋๋ค.
ํน์ ํฌ๋งท ์ง์ ์ฌ๋ถ๋ฅผ ํ์ธํ๋ ค๋ฉด ImageDecoder.isTypeSupported(mimeType) ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ํ์ฌ ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ ํน์ ํฌ๋งท์ด ์ง์๋๋์ง ๋์ ์ผ๋ก ํ์ธํ ์ ์์ต๋๋ค.
์์ : AVIF ์ง์ ํ์ธ
```javascript if (ImageDecoder.isTypeSupported('image/avif')) { console.log('AVIF๊ฐ ์ง์๋ฉ๋๋ค!'); } else { console.log('AVIF๊ฐ ์ง์๋์ง ์์ต๋๋ค.'); } ```
ImageDecoder ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
ImageDecoder๋ฅผ ์ฌ์ฉํ๋ ๊ณผ์ ์ ์ฌ๋ฌ ๋จ๊ณ๋ก ์ด๋ฃจ์ด์ง๋๋ค:
- ImageDecoder ์ธ์คํด์ค ์์ฑ: ์ํ๋ ์ด๋ฏธ์ง ํฌ๋งท์ ์ง์ ํ์ฌ
ImageDecoder๊ฐ์ฒด๋ฅผ ์ธ์คํด์คํํฉ๋๋ค. - ์ด๋ฏธ์ง ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ: ํ์ผ์ด๋ ๋คํธ์ํฌ ์์ค์์ ์ด๋ฏธ์ง ๋ฐ์ดํฐ๋ฅผ ๋ก๋ํฉ๋๋ค.
- ์ด๋ฏธ์ง ๋์ฝ๋ฉ: ์ด๋ฏธ์ง ๋ฐ์ดํฐ๋ฅผ
ImageDecoder์decode()๋ฉ์๋์ ์ ๋ฌํฉ๋๋ค. - ๋์ฝ๋ฉ๋ ํ๋ ์ ์ฒ๋ฆฌ: ๋์ฝ๋ฉ๋ ์ด๋ฏธ์ง ํ๋ ์์ ์ถ์ถํ๊ณ ํ์์ ๋ฐ๋ผ ์ฒ๋ฆฌํฉ๋๋ค.
์์ : JPEG ์ด๋ฏธ์ง ๋์ฝ๋ฉ
```javascript async function decodeJpeg(imageData) { try { const decoder = new ImageDecoder({ data: imageData, type: 'image/jpeg', }); const frame = await decoder.decode(); // ๋์ฝ๋ฉ๋ ํ๋ ์ ์ฒ๋ฆฌ const bitmap = frame.image; // ์์ : ์บ๋ฒ์ค์ ๋นํธ๋งต ๊ทธ๋ฆฌ๊ธฐ const canvas = document.createElement('canvas'); canvas.width = bitmap.width; canvas.height = bitmap.height; const ctx = canvas.getContext('2d'); ctx.drawImage(bitmap, 0, 0); document.body.appendChild(canvas); bitmap.close(); // ๋นํธ๋งต์ ๋ฆฌ์์ค ํด์ } catch (error) { console.error('์ด๋ฏธ์ง ๋์ฝ๋ฉ ์ค๋ฅ:', error); } } // ์ด๋ฏธ์ง ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ (fetch API ์ฌ์ฉ ์์ ) async function loadImage(url) { const response = await fetch(url); const arrayBuffer = await response.arrayBuffer(); decodeJpeg(arrayBuffer); } // ์ฌ์ฉ ์์ : loadImage('image.jpg'); // ์์ ์ ์ด๋ฏธ์ง URL๋ก ๊ต์ฒดํ์ธ์ ```
์ค๋ช :
decodeJpegํจ์๋imageDataArrayBuffer๋ฅผ ์ ๋ ฅ์ผ๋ก ๋ฐ์ต๋๋ค.data(์ด๋ฏธ์ง ๋ฐ์ดํฐ ์์ฒด)์type(์ด๋ฏธ์ง์ MIME ํ์ , ์ด ๊ฒฝ์ฐ 'image/jpeg')์ ์ง์ ํ์ฌ ์๋ก์ดImageDecoder์ธ์คํด์ค๋ฅผ ์์ฑํฉ๋๋ค.decoder.decode()๋ฉ์๋๋ ์ด๋ฏธ์ง ๋ฐ์ดํฐ๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ๋์ฝ๋ฉํ๊ณVideoFrame๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค.frame.image์์ฑ์ ๋์ฝ๋ฉ๋ ์ด๋ฏธ์ง์VideoFrame์ผ๋ก ์ ๊ทผํ ์ ์๊ฒ ํด์ค๋๋ค.- ๊ทธ๋ฐ ๋ค์ ์์ ์์๋ ์บ๋ฒ์ค ์์๋ฅผ ์์ฑํ๊ณ ๋์ฝ๋ฉ๋ ์ด๋ฏธ์ง๋ฅผ ๊ทธ ์์ ๊ทธ๋ ค์ ํ์ํฉ๋๋ค.
- ๋ง์ง๋ง์ผ๋ก,
VideoFrame์ด ์ฐจ์งํ๊ณ ์๋ ๋ฆฌ์์ค๋ฅผ ํด์ ํ๊ธฐ ์ํดbitmap.close()๋ฅผ ํธ์ถํฉ๋๋ค. ์ด๊ฒ์ ํจ์จ์ ์ธ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ๋ฅผ ์ํด ๋งค์ฐ ์ค์ํฉ๋๋ค.close()๋ฅผ ํธ์ถํ์ง ์์ผ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
๊ณ ๊ธ ์ฌ์ฉ๋ฒ ๋ฐ ์ฌ์ฉ์ ์ ์
ImageDecoder๋ ๋์ฝ๋ฉ ํ๋ก์ธ์ค๋ฅผ ์ฌ์ฉ์ ์ ์ํ๊ธฐ ์ํ ์ฌ๋ฌ ์ต์
์ ์ ๊ณตํฉ๋๋ค. ์ด๋ฌํ ์ต์
์ ์ค์ผ์ผ๋ง, ์ ๊ณต๊ฐ ๋ณํ, ํ๋ ์ ์ ํ ๋ฑ ๋์ฝ๋ฉ์ ๋ค์ํ ์ธก๋ฉด์ ์ ์ดํ๋ ๋ฐ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋์ฝ๋ฉ ์ต์
decode() ๋ฉ์๋๋ ๋ค์ํ ๋์ฝ๋ฉ ๋งค๊ฐ๋ณ์๋ฅผ ์ง์ ํ ์ ์๋ ์ ํ์ options ๊ฐ์ฒด๋ฅผ ๋ฐ์ต๋๋ค.
completeFrames: ์ด๋ฏธ์ง์ ๋ชจ๋ ํ๋ ์์ ๋์ฝ๋ฉํ ์ง ์ฒซ ๋ฒ์งธ ํ๋ ์๋ง ๋์ฝ๋ฉํ ์ง๋ฅผ ๋ํ๋ด๋ ๋ถ๋ฆฌ์ธ ๊ฐ์ ๋๋ค. ๊ธฐ๋ณธ๊ฐ์ `false`์ ๋๋ค.frameIndex: ๋์ฝ๋ฉํ ํ๋ ์์ ์ธ๋ฑ์ค์ ๋๋ค (๋ค์ค ํ๋ ์ ์ด๋ฏธ์ง์ฉ). ๊ธฐ๋ณธ๊ฐ์ 0์ ๋๋ค.
์์ : ๋ค์ค ํ๋ ์ ์ด๋ฏธ์ง(์: GIF)์์ ํน์ ํ๋ ์ ๋์ฝ๋ฉ
```javascript async function decodeGifFrame(imageData, frameIndex) { try { const decoder = new ImageDecoder({ data: imageData, type: 'image/gif', }); const frame = await decoder.decode({ frameIndex: frameIndex, }); // ๋์ฝ๋ฉ๋ ํ๋ ์ ์ฒ๋ฆฌ const bitmap = frame.image; // ์์ : ์บ๋ฒ์ค์ ๋นํธ๋งต ๊ทธ๋ฆฌ๊ธฐ const canvas = document.createElement('canvas'); canvas.width = bitmap.width; canvas.height = bitmap.height; const ctx = canvas.getContext('2d'); ctx.drawImage(bitmap, 0, 0); document.body.appendChild(canvas); bitmap.close(); // ๋นํธ๋งต์ ๋ฆฌ์์ค ํด์ } catch (error) { console.error('์ด๋ฏธ์ง ๋์ฝ๋ฉ ์ค๋ฅ:', error); } } // ์ฌ์ฉ ์์ : // 'gifData'๋ผ๋ ArrayBuffer์ GIF ์ด๋ฏธ์ง ๋ฐ์ดํฐ๊ฐ ์๋ค๊ณ ๊ฐ์ ํฉ๋๋ค decodeGifFrame(gifData, 2); // 3๋ฒ์งธ ํ๋ ์(์ธ๋ฑ์ค 2) ๋์ฝ๋ฉ ```
์ค๋ฅ ์ฒ๋ฆฌ
๋์ฝ๋ฉ ๊ณผ์ ์์ ๋ฐ์ํ ์ ์๋ ์ ์ฌ์ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ์ด๋ฏธ์ง ๋ฐ์ดํฐ๋ ๋์ฝ๋ฉ ํ๋ก์ธ์ค ์์ฒด์ ๋ฌธ์ ๊ฐ ์๋ ๊ฒฝ์ฐ decode() ๋ฉ์๋๋ ์์ธ๋ฅผ ๋ฐ์์ํฌ ์ ์์ต๋๋ค. ์ด๋ฌํ ์ค๋ฅ๋ฅผ ์ ์์ ์ผ๋ก ํฌ์ฐฉํ๊ณ ์ฒ๋ฆฌํ๋ ค๋ฉด ๋์ฝ๋ฉ ์ฝ๋๋ฅผ try...catch ๋ธ๋ก์ผ๋ก ๊ฐ์ธ์ผ ํฉ๋๋ค.
์์ : try...catch๋ฅผ ์ฌ์ฉํ ์ค๋ฅ ์ฒ๋ฆฌ
```javascript async function decodeImage(imageData, mimeType) { try { const decoder = new ImageDecoder({ data: imageData, type: mimeType, }); const frame = await decoder.decode(); // ๋์ฝ๋ฉ๋ ํ๋ ์ ์ฒ๋ฆฌ const bitmap = frame.image; // ... (๋๋จธ์ง ์ฝ๋) bitmap.close(); // ๋นํธ๋งต์ ๋ฆฌ์์ค ํด์ } catch (error) { console.error('์ด๋ฏธ์ง ๋์ฝ๋ฉ ์ค๋ฅ:', error); // ์ค๋ฅ ์ฒ๋ฆฌ (์: ์ฌ์ฉ์์๊ฒ ์ค๋ฅ ๋ฉ์์ง ํ์) } } ```
์ฑ๋ฅ ๊ณ ๋ ค์ฌํญ
ImageDecoder๋ ์๋ฐ์คํฌ๋ฆฝํธ ๊ธฐ๋ฐ ์ด๋ฏธ์ง ์ฒ๋ฆฌ์ ๋นํด ์๋นํ ์ฑ๋ฅ ์ด์ ์ ์ ๊ณตํ์ง๋ง, ์ฑ๋ฅ์ ๋์ฑ ์ต์ ํํ๊ธฐ ์ํด ํน์ ์์๋ฅผ ๊ณ ๋ คํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค:
- ์ด๋ฏธ์ง ํฌ๋งท: ์ฝํ ์ธ ์ ์ฌ์ฉ ์ฌ๋ก์ ๋ฐ๋ผ ์ ์ ํ ์ด๋ฏธ์ง ํฌ๋งท์ ์ ํํ์ธ์. WebP์ AVIF๋ ์ผ๋ฐ์ ์ผ๋ก JPEG์ PNG๋ณด๋ค ๋ ๋์ ์์ถ๋ฅ ๊ณผ ํ์ง์ ์ ๊ณตํฉ๋๋ค.
- ์ด๋ฏธ์ง ํฌ๊ธฐ: ์ ํ๋ฆฌ์ผ์ด์ ์ ํ์ํ ์ต์ ํฌ๊ธฐ๋ก ์ด๋ฏธ์ง ํฌ๊ธฐ๋ฅผ ์ค์ด์ธ์. ํฐ ์ด๋ฏธ์ง๋ ๋ ๋ง์ ๋ฉ๋ชจ๋ฆฌ์ ์ฒ๋ฆฌ ๋ฅ๋ ฅ์ ์๋นํฉ๋๋ค.
- ๋์ฝ๋ฉ ์ต์ : ์ฒ๋ฆฌ ์ค๋ฒํค๋๋ฅผ ์ต์ํํ๊ธฐ ์ํด ์ ์ ํ ๋์ฝ๋ฉ ์ต์ ์ ์ฌ์ฉํ์ธ์. ์๋ฅผ ๋ค์ด, ์ธ๋ค์ผ๋ง ํ์ํ ๊ฒฝ์ฐ ์ด๋ฏธ์ง์ ๋ ์์ ๋ฒ์ ์ ๋์ฝ๋ฉํ์ธ์.
- ๋น๋๊ธฐ ์์ : ๋ฉ์ธ ์ค๋ ๋๋ฅผ ์ฐจ๋จํ์ง ์๋๋ก ํญ์ ๋น๋๊ธฐ API๋ฅผ ์ฌ์ฉํ์ธ์.
- ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ: ์ด์ ์ ๊ฐ์กฐํ๋ฏ์ด, ๋์ฝ๋ฉ์์ ์ป์
VideoFrame๊ฐ์ฒด์ ๋ํด ํญ์bitmap.close()๋ฅผ ํธ์ถํ์ฌ ๊ธฐ๋ณธ ๋ฉ๋ชจ๋ฆฌ ๋ฆฌ์์ค๋ฅผ ํด์ ํ์ธ์. ์ด๋ฅผ ์ํํ์ง ์์ผ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํ๊ณ ์ฑ๋ฅ์ด ์ ํ๋ฉ๋๋ค. - ์น ์์ปค: ๊ณ์ฐ ์ง์ฝ์ ์ธ ์์ ์ ๊ฒฝ์ฐ, ์ด๋ฏธ์ง ์ฒ๋ฆฌ๋ฅผ ๋ณ๋์ ์ค๋ ๋๋ก ์คํ๋ก๋ํ๊ธฐ ์ํด ์น ์์ปค ์ฌ์ฉ์ ๊ณ ๋ คํ์ธ์.
์ฌ์ฉ ์ฌ๋ก
ImageDecoder๋ ๊ณ ๊ธ ์ด๋ฏธ์ง ์ฒ๋ฆฌ ๊ธฐ๋ฅ์ด ํ์ํ ๊ด๋ฒ์ํ ์น ์ ํ๋ฆฌ์ผ์ด์
์์ ์ฌ์ฉ๋ ์ ์์ต๋๋ค:
- ์ด๋ฏธ์ง ํธ์ง๊ธฐ: ํฌ๊ธฐ ์กฐ์ , ์๋ฅด๊ธฐ, ํํฐ๋ง๊ณผ ๊ฐ์ ์ด๋ฏธ์ง ํธ์ง ๊ธฐ๋ฅ ๊ตฌํ.
- ์ด๋ฏธ์ง ๋ทฐ์ด: ํฌ๊ณ ๋ณต์กํ ์ด๋ฏธ์ง๋ฅผ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ ๊ณ ์ฑ๋ฅ ์ด๋ฏธ์ง ๋ทฐ์ด ์ ์.
- ์ด๋ฏธ์ง ๊ฐค๋ฌ๋ฆฌ: ํ๋, ์ด๋, ์ ํ๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ ๊ฐ์ถ ๋์ ์ด๋ฏธ์ง ๊ฐค๋ฌ๋ฆฌ ๊ตฌ์ถ.
- ์ปดํจํฐ ๋น์ ์ ํ๋ฆฌ์ผ์ด์ : ์ค์๊ฐ ์ด๋ฏธ์ง ๋ถ์์ด ํ์ํ ์น ๊ธฐ๋ฐ ์ปดํจํฐ ๋น์ ์ ํ๋ฆฌ์ผ์ด์ ๊ฐ๋ฐ.
- ๊ฒ์ ๊ฐ๋ฐ: ํ ์ค์ฒ ๋ฐ ์คํ๋ผ์ดํธ ๋ก๋ฉ์ ์ํด ์น ๊ฒ์์ ์ด๋ฏธ์ง ๋์ฝ๋ฉ ํตํฉ.
- ๋ผ์ด๋ธ ์คํธ๋ฆฌ๋ฐ: ๋ ๋๋ง ๋ฐ ์ฒ๋ฆฌ๋ฅผ ์ํด ๋ผ์ด๋ธ ๋น๋์ค ์คํธ๋ฆผ์ ๊ฐ๋ณ ํ๋ ์ ๋์ฝ๋ฉ.
- ์ฆ๊ฐ ํ์ค(AR): AR ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํด ์นด๋ฉ๋ผ์์ ์บก์ฒํ ์ด๋ฏธ์ง ๋์ฝ๋ฉ.
- ์๋ฃ ์์: ์น ๊ธฐ๋ฐ ์ง๋จ ๋๊ตฌ์์ ์๋ฃ ์ด๋ฏธ์ง ํ์ ๋ฐ ์ฒ๋ฆฌ.
์์ : ์น ์์ปค๋ฅผ ์ฌ์ฉํ ์ด๋ฏธ์ง ์ฒ๋ฆฌ
์ด ์์ ๋ ์น ์์ปค๋ฅผ ์ฌ์ฉํ์ฌ ๋ณ๋์ ์ค๋ ๋์์ ์ด๋ฏธ์ง๋ฅผ ๋์ฝ๋ฉํ์ฌ ๋ฉ์ธ ์ค๋ ๋๊ฐ ์ฐจ๋จ๋๋ ๊ฒ์ ๋ฐฉ์งํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค.
main.js:
```javascript // ์๋ก์ด ์น ์์ปค ์์ฑ const worker = new Worker('worker.js'); // ์์ปค๋ก๋ถํฐ ๋ฉ์์ง ์์ ๋๊ธฐ worker.onmessage = function(event) { const bitmap = event.data; // ๋์ฝ๋ฉ๋ ๋นํธ๋งต ์ฒ๋ฆฌ const canvas = document.createElement('canvas'); canvas.width = bitmap.width; canvas.height = bitmap.height; const ctx = canvas.getContext('2d'); ctx.drawImage(bitmap, 0, 0); document.body.appendChild(canvas); bitmap.close(); // ๋ฆฌ์์ค ํด์ . }; // ์ด๋ฏธ์ง ๋ฐ์ดํฐ ๋ก๋ async function loadImage(url) { const response = await fetch(url); const arrayBuffer = await response.arrayBuffer(); // ์์ปค์ ์ด๋ฏธ์ง ๋ฐ์ดํฐ ์ ์ก worker.postMessage({ imageData: arrayBuffer, type: 'image/jpeg' }, [arrayBuffer]); // ์ฑ๋ฅ์ ์ํ ์ ์ก ๊ฐ๋ฅ ๊ฐ์ฒด(Transferable object) } // ์ฌ์ฉ ์์ : loadImage('image.jpg'); ```
worker.js:
```javascript // ๋ฉ์ธ ์ค๋ ๋๋ก๋ถํฐ ๋ฉ์์ง ์์ ๋๊ธฐ self.onmessage = async function(event) { const imageData = event.data.imageData; const type = event.data.type; try { const decoder = new ImageDecoder({ data: imageData, type: type, }); const frame = await decoder.decode(); const bitmap = frame.image; // ๋์ฝ๋ฉ๋ ๋นํธ๋งต์ ๋ฉ์ธ ์ค๋ ๋๋ก ๋ค์ ์ ์ก self.postMessage(bitmap, [bitmap]); // ์ฑ๋ฅ์ ์ํ ์ ์ก ๊ฐ๋ฅ ๊ฐ์ฒด(Transferable object) } catch (error) { console.error('์์ปค์์ ์ด๋ฏธ์ง ๋์ฝ๋ฉ ์ค๋ฅ:', error); } }; ```
์น ์์ปค์ ๋ํ ์ค์ ๊ณ ๋ ค์ฌํญ:
- ์ ์ก ๊ฐ๋ฅ ๊ฐ์ฒด(Transferable Objects): ์น ์์ปค ์์ ์
postMessage๋ฉ์๋๋ ์ ์ก ๊ฐ๋ฅ ๊ฐ์ฒด(์ด๋ฏธ์ง ๋ฐ์ดํฐ ๋ฐ ๋์ฝ๋ฉ๋ ๋นํธ๋งต)๋ฅผ ํ์ฉํฉ๋๋ค. ์ด๋ ์ค์ํ ์ต์ ํ ๊ธฐ๋ฒ์ ๋๋ค. ๋ฉ์ธ ์ค๋ ๋์ ์์ปค ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ *๋ณต์ฌ*ํ๋ ๋์ , ๊ธฐ๋ณธ ๋ฉ๋ชจ๋ฆฌ ๋ฒํผ์ *์์ ๊ถ*์ด ์ด์ ๋ฉ๋๋ค. ์ด๋ ํนํ ๋์ฉ๋ ์ด๋ฏธ์ง์ ๊ฒฝ์ฐ ๋ฐ์ดํฐ ์ ์ก ์ค๋ฒํค๋๋ฅผ ํฌ๊ฒ ์ค์ ๋๋ค. ๋ฐฐ์ด ๋ฒํผ๋postMessage์ ๋ ๋ฒ์งธ ์ธ์๋ก ์ ๋ฌ๋์ด์ผ ํฉ๋๋ค. - Self.close(): ์์ปค๊ฐ ๋จ์ผ ์์
์ ์ํํ ํ ๋ ์ด์ ํ ์ผ์ด ์๋ค๋ฉด, ์์
์ ๋ง์น๊ณ ๋ฉ์ธ ์ค๋ ๋๋ก ๋ฐ์ดํฐ๋ฅผ ๋ค์ ๋ณด๋ธ ํ ์์ปค์์
self.close()๋ฅผ ํธ์ถํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ด๋ ์์ปค ๋ฆฌ์์ค๋ฅผ ํด์ ํ๋ฉฐ, ๋ชจ๋ฐ์ผ๊ณผ ๊ฐ์ด ๋ฆฌ์์ค ์ ์ฝ์ด ์๋ ํ๊ฒฝ์์ ์ค์ํ ์ ์์ต๋๋ค.
ImageDecoder์ ๋์
ImageDecoder๋ ์ด๋ฏธ์ง๋ฅผ ๋์ฝ๋ฉํ๋ ๊ฐ๋ ฅํ๊ณ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ ์ ๊ณตํ์ง๋ง, ํน์ ์ํฉ์์ ์ฌ์ฉํ ์ ์๋ ๋์์ ์ธ ์ ๊ทผ ๋ฐฉ์๋ ์์ต๋๋ค:
- Canvas API: Canvas API๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฏธ์ง๋ฅผ ๋์ฝ๋ฉํ ์ ์์ง๋ง, ์ด๋ ๋ธ๋ผ์ฐ์ ์ ๋ด์ฅ ์ด๋ฏธ์ง ์ฒ๋ฆฌ์ ์์กดํ๋ฉฐ
ImageDecoder์ ๋์ผํ ์์ค์ ์ ์ด ๋ฐ ์ฑ๋ฅ์ ์ ๊ณตํ์ง ์์ต๋๋ค. - ์๋ฐ์คํฌ๋ฆฝํธ ์ด๋ฏธ์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ: ์ฌ๋ฌ ์๋ฐ์คํฌ๋ฆฝํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ด๋ฏธ์ง ๋์ฝ๋ฉ ๋ฐ ์ฒ๋ฆฌ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ง๋ง, ์ข ์ข ์๋ฐ์คํฌ๋ฆฝํธ ๊ธฐ๋ฐ ๊ตฌํ์ ์์กดํ๋ฏ๋ก ๋ค์ดํฐ๋ธ ์ฝ๋ฑ๋ณด๋ค ๋๋ฆด ์ ์์ต๋๋ค. ์๋ก๋ jimp์ sharp(Node.js ๊ธฐ๋ฐ)๊ฐ ์์ต๋๋ค.
- ๋ธ๋ผ์ฐ์ ๋ด์ฅ ์ด๋ฏธ์ง ๋์ฝ๋ฉ:
<img>์์๋ฅผ ์ฌ์ฉํ๋ ์ ํต์ ์ธ ๋ฐฉ๋ฒ์ ๋ธ๋ผ์ฐ์ ์ ๋ด์ฅ ์ด๋ฏธ์ง ๋์ฝ๋ฉ์ ์์กดํฉ๋๋ค. ๊ฐ๋จํ์ง๋งImageDecoder๊ฐ ์ ๊ณตํ๋ ์ธ๋ฐํ ์ ์ด ๊ธฐ๋ฅ์ ์ ๊ณตํ์ง ์์ต๋๋ค.
๋ธ๋ผ์ฐ์ ํธํ์ฑ
WebCodecs์ ImageDecoder API๋ ๋น๊ต์ ์๋ก์ด ๊ธฐ์ ์ด๋ฉฐ, ๋ธ๋ผ์ฐ์ ์ง์์ ์์ง ๋ฐ์ ์ค์
๋๋ค. 2023๋
๋ง ๊ธฐ์ค์ผ๋ก Chrome, Firefox, Safari, Edge์ ๊ฐ์ ์ฃผ์ ๋ธ๋ผ์ฐ์ ๋ค์ WebCodecs ์ง์์ ๊ตฌํํ์ง๋ง, ํน์ ๊ธฐ๋ฅ๊ณผ ์ฑ๋ฅ์ ๋ค๋ฅผ ์ ์์ต๋๋ค.
๋ธ๋ผ์ฐ์ ์ง์์ ๋ํ ์ต์ ์ ๋ณด๋ ๋ธ๋ผ์ฐ์ ํธํ์ฑ ํ๋ฅผ ํ์ธํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ImageDecoder.isTypeSupported() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ํ์ฌ ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ ํน์ ์ด๋ฏธ์ง ํฌ๋งท์ด ์ง์๋๋์ง ๋์ ์ผ๋ก ํ์ธํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด WebCodecs๋ ํน์ ์ด๋ฏธ์ง ํฌ๋งท์ ์ง์ํ์ง ์๋ ๋ธ๋ผ์ฐ์ ๋ฅผ ์ํ ๋์ฒด ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํ ์ ์์ต๋๋ค.
ํฅํ ๊ฐ๋ฐ ๋ฐฉํฅ
WebCodecs API๋ ์งํํ๋ ๊ธฐ์ ์ด๋ฉฐ, ํฅํ ๊ฐ๋ฐ์ ํตํด ๊ทธ ๊ธฐ๋ฅ์ด ๋์ฑ ํฅ์๋๊ณ ์ฑํ์ด ํ๋๋ ๊ฒ์ผ๋ก ์์๋ฉ๋๋ค. ์ ์ฌ์ ์ธ ํฅํ ๊ฐ๋ฐ ์ฌํญ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ํ์ฅ๋ ํฌ๋งท ์ง์: ์๋ก์ด ์ฝ๋ฑ ๋ฐ ํน์ ํฌ๋งท์ ํฌํจํ ๋ ๋ง์ ์ด๋ฏธ์ง ํฌ๋งท ์ง์ ์ถ๊ฐ.
- ์ฑ๋ฅ ํฅ์: ๊ธฐ๋ณธ ์ฝ๋ฑ ๋ฐ API์ ์ฑ๋ฅ ์ต์ ํ.
- ๊ณ ๊ธ ๋์ฝ๋ฉ ์ต์ : ๋์ฝ๋ฉ ํ๋ก์ธ์ค์ ๋ํ ์ธ๋ฐํ ์ ์ด๋ฅผ ์ํ ๋ ๋ง์ ๊ณ ๊ธ ๋์ฝ๋ฉ ์ต์ ๋์ .
- WebAssembly์์ ํตํฉ: ์ฑ๋ฅ ๋ฐ ์ ์ฐ์ฑ ํฅ์์ ์ํ WebAssembly ๊ธฐ๋ฐ ์ฝ๋ฑ ์ฌ์ฉ ์ง์.
๊ฒฐ๋ก
WebCodecs ImageDecoder API๋ ํ๋ ์น ๊ฐ๋ฐ์ ์ํ ๊ฐ๋ ฅํ ๋๊ตฌ๋ก, ์น ์ ํ๋ฆฌ์ผ์ด์
์ ์ด๋ฏธ์ง ์ฒ๋ฆฌ์ ์ ๋ก ์๋ ์ ์ด์ ์ฑ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ๊ฐ๋ฐ์๋ ๋ธ๋ผ์ฐ์ ์ ๋ด์ฅ ์ฝ๋ฑ์ ํ์ฉํ์ฌ ๊ณ ๊ธ ์ด๋ฏธ์ง ์กฐ์ ๊ธฐ๋ฅ์ด ํ์ํ ๊ณ ์ฑ๋ฅ ์ด๋ฏธ์ง ํธ์ง๊ธฐ, ๋ทฐ์ด ๋ฐ ๊ธฐํ ์ ํ๋ฆฌ์ผ์ด์
์ ๋ง๋ค ์ ์์ต๋๋ค. WebCodecs์ ๋ํ ๋ธ๋ผ์ฐ์ ์ง์์ด ๊ณ์ ์ฆ๊ฐํจ์ ๋ฐ๋ผ, ImageDecoder๋ ์น ๋ฉํฐ๋ฏธ๋์ด์ ํ๊ณ๋ฅผ ๋ฐ์ด๋๊ณ ์ ํ๋ ์น ๊ฐ๋ฐ์์๊ฒ ์ ์ ๋ ์ค์ํ ๋๊ตฌ๊ฐ ๋ ๊ฒ์
๋๋ค.
์ด ๊ฐ์ด๋์์ ์ ์๋ ๊ฐ๋
๊ณผ ๊ธฐ์ ์ ์ดํดํจ์ผ๋ก์จ, ์ด์ ์๋ ๋ถ๊ฐ๋ฅํ๋ ํ์ ์ ์ด๊ณ ๋งค๋ ฅ์ ์ธ ์น ๊ฒฝํ์ ๋ง๋ค๊ธฐ ์ํด ImageDecoder์ ํ์ ํ์ฉํ ์ ์์ต๋๋ค.